/*
    mathtools, a calculator-complimentary application for math studies
    Copyright (C) 2009 Irving Axel Jounior Rivas Zarete

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    If you need to contact me, please do so: axel (period) rivas (inside) gmail (dot) com
*/
#include <stdlib.h>

/*
Function Declaration.
	int esprimo(int num);
		returns 1 if num is prime, else returns 0
	int *fprimos(int num);
		Returns a pointer; the value pointed to is the amount
		of prime factors for the num, and the factors are allocated
		in contiguous spaces starting from the pointers' position+1
	int mcm(int* nums);
		recieves an array of numbers, the first of which is the amount
		of numbers for which the LCM is sought.
		returns the GCD.
*/

int *fprimos(int num){
	//plh is a placeholder for num
	//represents the current number being examined for prime factors
	int i, plh = num,*ptr,cuantos=0;
	//this loop is used to count the number of factors
	//done in order to allocate memory for them later on.
	for(i = 2;i <= plh;i++){
		if(plh%i == 0){
			//if plh is divisible by the current iteration (value of i)
			//plh is divided by i (as i is a factor of plh).
			//i is reduced by one, just to check for multiplicity
			//(that is, if the next value of plh is still divisible by the same number)
			plh/=i;
			//cuantos is counting how many prime factors we have.
			cuantos++;
			i = i-1;
		}
	}
	//allocating memory for the pointer.
	ptr = malloc(sizeof(int)*(cuantos+1));
	//putting the amount of factors found in the first position of the pointer.
	ptr[0] = cuantos;
	//resetting the count
	cuantos = 0;
	//resetting plh to the main value.
	plh = num;
	//this loop is used to store the factors in memory.
	for(i = 2;i <= plh;i++){
			//if plh is divisible by the current iteration (value of i)
			//plh is divided by i (as i is a factor of plh).
			//i is reduced by one, just to check for multiplicity
			//(that is, if the next value of plh is still divisible by the same number)
		if( plh%i == 0){
			plh /= i;
			cuantos++;
			//storing the factor in memory
			ptr[cuantos] = i;
			i = i - 1;
		}
	}
	return ptr;
}

int esprimo(int num){	int i;
	//loop to check if num is not a prime number.	for(i = 2;i < num / 2;i ++){		if( (num % i) == 0){			return 0;		}	}	return 1;}

int mincommult(int* nums){
        //i and j are iterators.
        //sm will hold the smallest of the numbers we'll look the LCM for
        //d is used for the second loop. Details there.
        int i,j,sm=nums[1],mcm=1,d=0;
 
        //loop to seek the smallest number in the group of numbers whose LCM we seek
        for(i=nums[0];i>0;i--){
                if(sm>nums[i]) sm = nums[i];
        } 
        //counting from 1 to the smallest number we look the LCM for. That is 'cause the LCM will never
        //be bigger than the smallest number we look LCM for. So i is actually probing the numbers to
        //check if it's divisible by anyone.
        for(i=1;i<sm;i++){
                        //initializing d
                        d=0;
                //j is used to iterate in the array of arguments
                for(j=1;j<nums[0];j++){
                        //if i is divisible by the current argument, augment the LCM by multiplying
                        //change the value of 'd' so that the number isn't multiplied unnecessarily
                        if(nums[j]%i==0 && d=0){
                                mcm*=i;
                                d++;
                                //reduce the argument by dividing.
                                nums[j]/=i;                            
                        }
                        //if an argument was divisible by i, don't increase the LCM, but do divide
                        if(nums[j]%i==0 && d=1){
                                nums[j]/=i;                            
                        }
                }
                //if the any argument was divisible by i, reduce i. Done to check for repeated factors
                if (d==1) i--;
        }       
	return mcm;
}
